package com.zk.stock.service.impl;

import com.alibaba.excel.analysis.v03.handlers.NoteRecordHandler;
import com.google.common.collect.Lists;
import com.zk.stock.mapper.StockBusinessMapper;
import com.zk.stock.mapper.StockMarketIndexInfoMapper;
import com.zk.stock.mapper.StockRtInfoMapper;
import com.zk.stock.pojo.entity.StockMarketIndexInfo;
import com.zk.stock.pojo.entity.StockRtInfo;
import com.zk.stock.pojo.vo.StockInfoConfig;
import com.zk.stock.service.StockTimerTaskService;
import com.zk.stock.utils.DateTimeUtil;
import com.zk.stock.utils.IdWorker;
import com.zk.stock.utils.ParseType;
import com.zk.stock.utils.ParserStockInfoUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.expression.DateTimeLiteralExpression;
import org.joda.time.DateTime;
import org.joda.time.LocalDateTime;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author 曹自康的Laptop
 * @version 1.0
 * @Date 2024-07-0314:37
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class StockTimerTaskServiceImpl implements StockTimerTaskService {
    private final RestTemplate restTemplate;
    private final StockInfoConfig stockInfoConfig;
    private final IdWorker idWorker;
    private final StockMarketIndexInfoMapper stockMarketIndexInfoMapper;
    private final StockBusinessMapper stockBusinessMapper;
    private final ParserStockInfoUtil parserStockInfoUtil;
    private final StockRtInfoMapper stockRtInfoMapper;
    /**
     * 获取国内大盘的实时数据信息
     */
    @Override
    public void getInnerMarketInfo() {
        // 1.采集原始数据
        String url = stockInfoConfig.getMarketUrl()+String.join(",",stockInfoConfig.getInner());

        HttpHeaders httpHeaders = new HttpHeaders();

        // 添加防盗链
        httpHeaders.add("Referer", "https://finance.sina.com.cn/stock/" );

        // 用户客户端标识
        httpHeaders.add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36");

        // 维护http请求实体的对象
        HttpEntity<Object> httpEntity = new HttpEntity<>(httpHeaders);

        // 发送请求
        ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.GET, httpEntity, String.class);
        if (responseEntity.getStatusCodeValue() != 200) {
            // 当前请求失败了
            log.error("当前时间点：{}，http状态码：{}", LocalDateTime.now(),responseEntity.getStatusCodeValue());
            return;
        }
        String jsData = responseEntity.getBody();
        System.out.println("jsData = " + jsData);


        // 2.java正则解析原始数据
        String reg ="var hq_str_(.+)=\"(.+)\";";

        Pattern pattern = Pattern.compile(reg);
        // 匹配字符串
        Matcher matcher = pattern.matcher(jsData);
        ArrayList<StockMarketIndexInfo> list = new ArrayList<>();

        while (matcher.find()){
            // 获取大盘的编码
            String marketCode = matcher.group(1);
            // 获取其他信息
            String OtherInfo = matcher.group(2);
            // 将other字符串以逗号切割，获取大片的向详细信息
            String[] splitArr = OtherInfo.split(",");
            //大盘名称
            String marketName=splitArr[0];
            //获取当前大盘的开盘点数
            BigDecimal openPoint=new BigDecimal(splitArr[1]);
            //前收盘点
            BigDecimal preClosePoint=new BigDecimal(splitArr[2]);
            //获取大盘的当前点数
            BigDecimal curPoint=new BigDecimal(splitArr[3]);
            //获取大盘最高点
            BigDecimal maxPoint=new BigDecimal(splitArr[4]);
            //获取大盘的最低点
            BigDecimal minPoint=new BigDecimal(splitArr[5]);
            //获取成交量
            Long tradeAmt=Long.valueOf(splitArr[8]);
            //获取成交金额
            BigDecimal tradeVol=new BigDecimal(splitArr[9]);
            //时间
            Date curTime = DateTimeUtil.getDateTimeWithoutSecond(splitArr[30] + " " + splitArr[31]).toDate();
            // 3.解析封装entity对象组装entity对象
            StockMarketIndexInfo info =  StockMarketIndexInfo.builder()
                    .id(idWorker.nextId())
                    .marketCode(marketCode)
                    .marketName(marketName)
                    .curPoint(curPoint)
                    .openPoint(openPoint)
                    .preClosePoint(preClosePoint)
                    .maxPoint(maxPoint)
                    .minPoint(minPoint)
                    .tradeVolume(tradeVol)
                    .tradeAmount(tradeAmt)
                    .curTime(curTime)
                    .build();
            //收集封装的对象，方便批量插入
            list.add(info);
        }
        System.out.println("list = " + list);

        // 4.调用Mybatis批量入库
      int count =  stockMarketIndexInfoMapper.insertBatch(list);

    }

    /**
     * 定义获取分钟级股票数据
     */
    @Override
    public void getStockRtIndex() {
        // 1.获取所有各股的集合3000+
        List<String> allStockCodes = stockBusinessMapper.getAllStockCodes();
        allStockCodes = allStockCodes.stream().map(code -> code.startsWith("6")?"sh"+code:"sz"+code).collect(Collectors.toList());
        // 将大的集合切分为若干的小集合，分批去采集数据
        Lists.partition(allStockCodes,15).forEach(codes ->{
            System.out.println("codes = " + codes);
            String url = stockInfoConfig.getMarketUrl()+String.join(",",codes);
            HttpHeaders httpHeaders = new HttpHeaders();

            // 添加防盗链
            httpHeaders.add("Referer", "https://finance.sina.com.cn/stock/" );

            // 用户客户端标识
            httpHeaders.add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36");

            // 维护http请求实体的对象
            HttpEntity<Object> httpEntity = new HttpEntity<>(httpHeaders);

            // 发送请求
            ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.GET, httpEntity, String.class);
            if (responseEntity.getStatusCodeValue() != 200) {
                // 当前请求失败了
                log.error("当前时间点：{}，http状态码：{}", LocalDateTime.now(),responseEntity.getStatusCodeValue());
                return;
            }
            // 获取js格式数据
            String jsData = responseEntity.getBody();
            List<StockRtInfo> list1 = parserStockInfoUtil.parser4StockOrMarketInfo(jsData, ParseType.ASHARE);
           // 批量保存采集的个股的数据
          int count =  stockRtInfoMapper.inserBatch(list1);
            System.out.println("插入成功了");

        });

    }
}
